package com.xxg.renrensearch.schedule;

import com.xxg.renrensearch.dao.*;
import com.xxg.renrensearch.es.RenRenShopEs;
import com.xxg.renrensearch.init.RenrenShopProductsInit;
import com.xxg.renrensearch.init.RenrenShopShopInit;
import com.xxg.renrensearch.repository.ProductRepository;
import com.xxg.renrensearch.service.BaiduService;
import com.xxg.renrensearch.service.DbService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 数据同步
 *
 * @author xuxiaogang
 * @date 2021-11-30
 */
@Component
public class SyncData {
    private final Logger logger = LoggerFactory.getLogger(SyncData.class);
    private final RenrenShopOperationLogDao renrenShopOperationLogDao;
    private final RenrenShopGoodsDao renrenShopGoodsDao;
    private final ProductRepository productRepository;
    private final RenRenShopEs renRenShopEs;
    private final RenrenShopGoodsCategoryMapDao renrenShopGoodsCategoryMapDao;
    private final RenrenShopGoodsOptionDao renrenShopGoodsOptionDao;
    private final RenrenShopProductsInit renrenShopProductsInit;
    private final RenrenShopShopInit renrenShopShopInit;
    private Date syncDate;
    private final BaiduService baiduService;
    private final DbService dbService;
    private final static String IP = "121.43.116.228";

    public SyncData(RenrenShopOperationLogDao renrenShopOperationLogDao, RenrenShopGoodsDao renrenShopGoodsDao,
                    ProductRepository productRepository, RenRenShopEs renRenShopEs,
                    RenrenShopGoodsCategoryMapDao renrenShopGoodsCategoryMapDao,
                    RenrenShopGoodsOptionDao renrenShopGoodsOptionDao, RenrenShopProductsInit renrenShopProductsInit,
                    RenrenShopShopInit renrenShopShopInit, BaiduService baiduService, DbService dbService) {
        this.renrenShopOperationLogDao = renrenShopOperationLogDao;
        this.renrenShopGoodsDao = renrenShopGoodsDao;
        this.productRepository = productRepository;
        this.renRenShopEs = renRenShopEs;
        this.renrenShopGoodsCategoryMapDao = renrenShopGoodsCategoryMapDao;
        this.renrenShopGoodsOptionDao = renrenShopGoodsOptionDao;
        this.renrenShopProductsInit = renrenShopProductsInit;
        this.renrenShopShopInit = renrenShopShopInit;
        this.baiduService = baiduService;
        this.dbService = dbService;
    }

    public void syncDataByTime(String startTime) {
        syncDate = new Date();
        // 根据时间查询日志
        List<RenrenShopOperationLog> logs = renrenShopOperationLogDao.selectByTime(startTime);
        // 商品操作映射
        Map<String, Integer> idOpMap = new HashMap<>(1000);
        Map<String, String> addLog = new HashMap<>(1000);
        for (RenrenShopOperationLog log : logs) {
            int opCode = log.getIdentifyCode();
            String rIds = log.getRelationIds();
            switch (opCode) {
                case 200000:
                    // 商品添加
                    idOpMap.put(rIds, 0);
                    // 带货或采集操作
                    if (IP.equals(log.getIp())) {
                        addLog.put(rIds, log.getPrimary());
                    }
                    break;
                case 200014:
                    // 商品批量上架Id
                    String[] idStr1 = rIds.split(",");
                    for (String idStr : idStr1) {
                        idOpMap.put(idStr, 0);
                    }
                    break;
                case 200001:
                    // 商品修改
                case 200005:
                    // 商品修改属性
                case 200010:
                    // 商品设置价格库存
                    idOpMap.put(rIds, 1);
                    break;
                case 200012:
                    // 商品批量下架
                case 200015:
                    // 商品批量删除
                    String[] idStr2 = rIds.split(",");
                    for (String idStr : idStr2) {
                        idOpMap.put(idStr, 2);
                    }
                    break;
                default:
                    break;
            }
        }
        // 同步店铺数据
        renrenShopShopInit.syncData();
        // 同步商品数据
        syncProductByLog(idOpMap, addLog);
    }

    /**
     * 同步商品数据
     *
     * @param idOpMap 商品操作映射
     * @param addLog  带货或采集日志
     */
    private void syncProductByLog(Map<String, Integer> idOpMap, Map<String, String> addLog) {
        logger.info("product sync start");
        List<Integer> addList = new LinkedList<>();
        List<Integer> updateList = new LinkedList<>();
        List<Integer> deleteList = new LinkedList<>();
        Map<Integer, String> carryGatherLog = new HashMap<>(addLog.size() * 4 / 3 + 1);
        for (Map.Entry<String, Integer> en : idOpMap.entrySet()) {
            int id = Integer.parseInt(en.getKey());
            int op = en.getValue();
            switch (op) {
                case 0:
                    // 新增
                    addList.add(id);
                    // 排除批量上架的干扰，获取真实的带货或采集的数据
                    if (addLog.containsKey(en.getKey())) {
                        carryGatherLog.put(id, addLog.get(en.getKey()));
                    }
                    break;
                case 1:
                    // 修改
                    updateList.add(id);
                    break;
                case 2:
                    // 删除
                    deleteList.add(id);
                    break;
                default:
                    break;
            }
        }
        // 检查带货和采集日志
        if (carryGatherLog.size() > 0) {
            dbService.checkNewProductCarryInfo(carryGatherLog);
        }
        // 根据spuId删除商品
        if (deleteList.size() > 0) {
            logger.info("delete products size:" + deleteList.size());
            renRenShopEs.deleteAllByIds(Product.class, "spuId", deleteList);
            dbService.deleteData(deleteList);
        }
        // 更新商品
        if (updateList.size() > 0) {
            logger.info("update products size:" + updateList.size());
            List<Product> uList = getProducts(updateList);
            renRenShopEs.updateGoodsIndex(uList);
            baiduService.addOrUpdatePicture(uList);
        }
        // 新增商品
        if (addList.size() > 0) {
            logger.info("add products size:" + addList.size());
            List<Product> aList = getProducts(addList);
            productRepository.saveAll(aList);
            baiduService.addOrUpdatePicture(aList);
        }
        logger.info("product sync end");
    }

    /**
     * 查询商品信息
     *
     * @param ids ID列表
     * @return 结果
     */
    private List<Product> getProducts(List<Integer> ids) {
        List<Product> list = new LinkedList<>();
        List<RenrenShopGoods> shopGoods = renrenShopGoodsDao.selectByIds(ids);
        Map<Integer, List<Integer>> categoryMap = getGoodCategoryMap(ids);
        List<RenrenShopGoodsOption> goodsOptions = renrenShopGoodsOptionDao.selectByIds(ids);
        Map<Integer, List<RenrenShopGoodsOption>> optionsMap = skuGroupBySpuId(shopGoods.size(), goodsOptions);
        shopGoods.forEach(e -> {
            e.setCategories(categoryMap.get(e.getId()));
            if (e.getHasOption()) {
                // 多规格商品
                if (optionsMap.containsKey(e.getId())) {
                    List<RenrenShopGoodsOption> options = optionsMap.get(e.getId());
                    list.addAll(renrenShopProductsInit.goodOption2Product(e, options));
                }
            } else {
                // 单规格商品
                list.add(renrenShopProductsInit.good2Product(e));
            }
        });
        return list;
    }

    /**
     * 查询商品映射
     *
     * @param ids Id列表
     * @return 结果
     */
    private Map<Integer, List<Integer>> getGoodCategoryMap(List<Integer> ids) {
        List<RenrenShopGoodsCategoryMap> categories = renrenShopGoodsCategoryMapDao.selectByGoodIds(ids);
        Map<Integer, List<Integer>> listMap = new HashMap<>(categories.size() * 4 / 3 + 1);
        categories.forEach(e -> {
            if (!listMap.containsKey(e.getGoodsId())) {
                listMap.put(e.getGoodsId(), new LinkedList<>());
            }
            listMap.get(e.getGoodsId()).add(e.getCategoryId());
        });
        return listMap;
    }

    /**
     * 多规格商品分组
     *
     * @param goodsOptions 多规格商品信息
     * @return 结果
     */
    private Map<Integer, List<RenrenShopGoodsOption>> skuGroupBySpuId(int size, List<RenrenShopGoodsOption> goodsOptions) {
        // 多规格商品SKU处理
        Map<Integer, List<RenrenShopGoodsOption>> optionsMap = new HashMap<>(size * 4 / 3 + 1);
        goodsOptions.forEach(e -> {
            if (!optionsMap.containsKey(e.getGoodsId())) {
                optionsMap.put(e.getGoodsId(), new LinkedList<>());
            }
            optionsMap.get(e.getGoodsId()).add(e);
        });
        return optionsMap;
    }

    /**
     * 获取同步的时间戳
     *
     * @return 时间戳
     */
    public String getSyncDateStr() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(syncDate);
    }
}
